package com.wsdk.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;

import com.wsdk.R;
import com.wsdk.bean.VersionStateData;
import com.wsdk.constants.GlobalData;
import com.wsdk.constants.UrlConstants;
import com.wsdk.service.BluetoothLeService;
import com.wsdk.util.BlueToothScanUtil;
import com.wsdk.util.ControlUtil;
import com.wsdk.util.FileMD5Util;
import com.wsdk.util.FileUtil;
import com.wsdk.util.LogUtil;
import com.wsdk.util.OkHttpUtil;
import com.wsdk.util.ParseBluetoothData;
import com.wsdk.util.ShowDialog;
import com.wsdk.util.ShowToast;
import com.wsdk.view.BaseDialog;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

@SuppressLint("Registered")
public class WsdkActivity
        extends AppCompatActivity {
    public static final String DOWNLOAD_FIRM_PATH = Environment.getExternalStorageDirectory()
            .getPath() + "/com.centling.seal.phone/download/firmware/";

    protected Context mContext;
    protected boolean isVisible;
    protected boolean isDestroy;
    protected boolean isCanConnectDevice;
    protected boolean isNoNeedDealWithResetKey;

    public void setCanConnectDevice(boolean canConnectDevice) {
        isCanConnectDevice = canConnectDevice;
    }

    public void setNoNeedDealWithResetKey(boolean noNeedDealWithResetKey) {
        isNoNeedDealWithResetKey = noNeedDealWithResetKey;
    }

    private String globalCode = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mContext = this;
        isDestroy = false;
        /*
          在特定的界面进行固件升级的检查
         */
        if (isCanConnectDevice) {
            dealWithUpdate();
        }

        fetchGlobalCode();

        blueToothScanUtil = new BlueToothScanUtil(mContext);
    }

    @SuppressLint({"HardwareIds"})
    private void fetchGlobalCode() {
        String imei = null;
        if (ContextCompat.checkSelfPermission(mContext,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            imei = new Random().toString();
            globalCode = imei + System.currentTimeMillis();
            return;
        }
        TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
                Context.TELEPHONY_SERVICE);
        if (telephonyManager != null) {
            imei = telephonyManager.getDeviceId();
        }
        if (imei == null) {
            imei = new Random().toString();
        }
        globalCode = imei + System.currentTimeMillis();
    }

    @Override
    protected void onStart() {
        super.onStart();
        isVisible = true;
        // refetch for sometime onCreate no permission
        if (TextUtils.isEmpty(globalCode)) {
            fetchGlobalCode();
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        isVisible = true;
    }

    @Override
    protected void onStop() {
        super.onStop();
        isVisible = false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        isDestroy = true;
        if (isCanConnectDevice) {
            unregisterReceiver(updateReceiver);
        }
        OkHttpUtil.cancelCallWithTag("OkHttpCall_" + this.hashCode());
    }

    protected void getEnqueue(String url, OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.getEnqueue(url, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void getEnqueueWithoutToken(String url, OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.getEnqueueWithoutToken(url, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void postJsonEnqueue(String url, Map<String, String> params,
                                   OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.postJsonEnqueue(url.contains(
                "?") ? (url + "&reqIdentifer=" + globalCode) : (url + "?reqIdentifer=" + globalCode),
                params, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void postJsonEnqueueWithoutBaseUrl(String url, Map<String, String> params,
                                                 OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.postJsonEnqueueWithoutBaseUrl(url.contains(
                "?") ? (url + "&reqIdentifer=" + globalCode) : (url + "?reqIdentifer=" + globalCode),
                params, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void putJsonEnqueue(String url, Map<String, String> params,
                                  OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.putJsonEnqueue(url, params, responseCallback, "OkHttpCall_" + this.hashCode());
    }

    protected void deleteJsonEnqueue(String url, Map<String, String> params,
                                     OkHttpUtil.NetCallBack responseCallback) {
        OkHttpUtil.deleteJsonEnqueue(url, params, responseCallback,
                "OkHttpCall_" + this.hashCode());
    }

    /**
     * common update logic
     */
    public ControlUtil controlUtil = new ControlUtil();
    public BlueToothScanUtil blueToothScanUtil;
    public String macAddress;
    public String sn;

    public void checkVersion() {
        if (!GlobalData.isConnect) {
            blueToothScanUtil.setMacAddress(macAddress);
            blueToothScanUtil.startSearchBlueDevice();
        } else {
            controlUtil.checkVersion();
        }
    }

    private String hasNewVersion;
    private String url;
    private String md5CodeFromServer;

    private PowerManager.WakeLock wakeLock;
    private int packageNo;

    private BaseDialog versionDialog;
    private TextView beginUpdate;
    private TextView cancelUpdate;
    private TextView tvUpdateHint;
    private TextView tvUpdateTitle;

    @SuppressLint("HandlerLeak")
    private Handler updateHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    beginUpdate.setVisibility(View.GONE);
                    cancelUpdate.setVisibility(View.GONE);
                    tvUpdateHint.setText("下载固件文件中...");
                    break;
                case 2:
                    tvUpdateHint.setText("固件升级中...");
                    break;
                case 3:
                    tvUpdateHint.setText("固件升级失败，请关闭重新连接设备");
                    tvUpdateTitle.setText("升级失败");
                    beginUpdate.setVisibility(View.VISIBLE);
                    beginUpdate.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            versionDialog.dismiss();
                        }
                    });
                    break;
                case 4:
                    tvUpdateHint.setText("固件升级成功，点击确认返回主页");
                    tvUpdateTitle.setText("升级成功");
                    beginUpdate.setVisibility(View.VISIBLE);
                    beginUpdate.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            versionDialog.dismiss();
                        }
                    });
                    break;
                case 5:
                    tvUpdateHint.setText("固件下载失败，请联系管理员");
                    tvUpdateTitle.setText("升级失败");
                    beginUpdate.setVisibility(View.VISIBLE);
                    beginUpdate.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            versionDialog.dismiss();
                        }
                    });
                    break;
                case 6:
                    tvUpdateHint.setText("文件校验失败，请重试");
                    tvUpdateTitle.setText("升级失败");
                    beginUpdate.setVisibility(View.VISIBLE);
                    beginUpdate.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            versionDialog.dismiss();
                            BluetoothLeService.disconnect();
                        }
                    });
                    break;
                default:
                    break;
            }
        }
    };
    /**
     * 广播接收器
     */
    protected BroadcastReceiver updateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            // perhaps none
            if (!isVisible) {
                return;
            }
            if (BluetoothLeService.ACTION_GATT_HARDWARE_CONNECTED.equals(action)) {
                GlobalData.isConnect = true;
                checkVersion();
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                byte[] data = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
                if (ParseBluetoothData.isCheckVersion(data)) {
                    LogUtil.d("Bluetooth Firm Update Visible:" + isVisible);
                    if (isVisible) {
                        VersionStateData versionStateData = ParseBluetoothData.parseVersion(data);
                        if (versionStateData != null) {
                            String firmVersion = versionStateData.getFirmwareVersion();
                            initialStatus = versionStateData.getInitialStatus();
                            GlobalData.versionV2 = firmVersion.startsWith("02");
                            checkFirmWareUpdate(firmVersion);
                        }
                    }
                } else if (ParseBluetoothData.updateVersion(data) == 0) {
                    packageNo = controlUtil.updateVersion2();
                } else if (ParseBluetoothData.updateVersion(data) == 1) {
                    /*
                      传输失败
                     */
                    updateHandler.sendEmptyMessage(3);
                } else if (ParseBluetoothData.updateVersion2(data, packageNo)) {
                    if (wakeLock != null && !wakeLock.isHeld()) {
                        wakeLock.acquire(600000);
                    }
                    packageNo = controlUtil.updateVersion3();
                    LogUtil.e("Update Firmware:" + controlUtil.sumDataBlock + "<-" + packageNo);
                    if (controlUtil.sumDataBlock == packageNo) {
                        updateHandler.sendEmptyMessage(4);
                        if (wakeLock != null && wakeLock.isHeld()) {
                            wakeLock.release();
                        }
                    }
                } else if (ParseBluetoothData.updateVersion3(data)) {
                    if (wakeLock != null) {
                        wakeLock.release();
                    }
                } else if (ParseBluetoothData.updateVersion2Fail(data)) {
                    controlUtil.retrainUpdate();
                } else if (ParseBluetoothData.updateVersion3Fail(data)) {
                    updateHandler.sendEmptyMessage(3);
                } else if (ParseBluetoothData.isSycTime(data)) {
                    // sync time
                    if (ParseBluetoothData.parseSyncTime(data)) {
                        GlobalData.selfCheckStatus = "0";
                        if (GlobalData.versionV2) {
                            feedbackToServerAndChooseUpdateMethod();
                        } else {
                            chooseUpdateMethod();
                        }
                    } else {
                        LogUtil.e("sync tim failed");
                        BluetoothLeService.disconnect();
                    }
                } else if (!isNoNeedDealWithResetKey && ParseBluetoothData.isInit(data)) {
                    // reset key
                    int ret;
                    if ((ret = ParseBluetoothData.parseInit(data)) == 0) {
                        syncTimeV1();
                    } else if (ret == 1) {
                        feedbackToServerAndFetchFourKey();
                    } else if (ret == 2) {
                        feedbackToServerAndSyncTime();
                    } else {
                        ShowToast.shortTime("重置key失败");
                    }
                }
            } else if (BluetoothLeService.ACTION_DEVICE_UPLEVEL_FAILED.equals(action)){
                updateHandler.sendEmptyMessage(3);
            }
        }
    };

    /**
     * 检查固件升级
     */
    private void dealWithUpdate() {
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (pm != null) {
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wakelock:btUpdate");
        }

        versionDialog = new BaseDialog(this);
        versionDialog.setContentView(View.inflate(mContext, R.layout.dialog_alert, null));
        versionDialog.setCancelable(false);
        beginUpdate = versionDialog.findViewById(R.id.tv_select_dialog_ok);
        cancelUpdate = versionDialog.findViewById(R.id.tv_select_dialog_cancel);
        tvUpdateHint = versionDialog.findViewById(R.id.tv_select_dialog_msg);
        tvUpdateTitle = versionDialog.findViewById(R.id.tv_edit_dialog_title);
        tvUpdateTitle.setText("固件升级");
        /*
          注册广播接收器
         */
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_HARDWARE_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(BluetoothLeService.ACTION_DEVICE_UPLEVEL_FAILED);
        registerReceiver(updateReceiver, intentFilter);
    }

    /**
     * 检查版本是否存在新版本
     * @param firmVersion firmVersion
     */
    public void checkFirmWareUpdate(final String firmVersion) {
        controlUtil = new ControlUtil(GlobalData.versionV2);
        LogUtil.d("Bluetooth Firm Update Check");
        Map<String, String> param = new HashMap<>();
        param.put("flag", "0");
        param.put("firmwareVersion", firmVersion);
        param.put("equipSn", sn);
        postJsonEnqueue(UrlConstants.FIRMWARE_VERSION, param, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject data = new JSONObject(json);
                    String newFirmwareVersion = data.optString("firmwareVersion");
                    tvUpdateTitle.setText("固件升级");
                    tvUpdateHint.setText(String.format(Locale.CHINA,
                            "检测到新固件，为保证设备正常使用，需立即升级，点击确定开始升级\n旧版本:%s\n新版本:%s", firmVersion,
                            newFirmwareVersion));
                    hasNewVersion = data.optString(
                            "firmhasNewVersion");
                    url = data.optString("firmdownloadUrl");
                    md5CodeFromServer = data.optString("fileMD5");
                    if (isNoNeedDealWithResetKey) {
                        if (GlobalData.versionV2) {
                            controlUtil.getSN();
                        } else {
                            syncTimeV1();
                        }
                    } else {
                        if (GlobalData.versionV2) {
                            String resetRepairKey = data.optString("resetRepairKey");
                            String resetKey = data.optString("resetKey");
                            String isInner = data.optString("equipType");
                            if (TextUtils.equals("1", resetRepairKey)) {
                                // reset repair
                                if (TextUtils.equals("0", isInner)) {
                                    ShowDialog.showConfirmDialog(mContext, "恢复工作模式",
                                            "检测到固件当前处于维修模式\n但设备无法通过蓝牙恢复\n请使用章盾进行恢复",
                                            new View.OnClickListener() {
                                                @Override
                                                public void onClick(View v) {
                                                    BluetoothLeService.disconnect();
                                                }
                                            });
                                } else {
                                    fetchMKeyForInit();
                                }
                            } else if (TextUtils.equals("1", resetKey)) {
                                fetchMKeyForInit();
                            } else {
                                syncTimeV2();
                            }
                        } else {
                            syncTimeV1();
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
                BluetoothLeService.disconnect();
            }
        });
    }

    public void syncTimeV1() {
        getEnqueue(UrlConstants.GET_SERVER_TIME, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    String returnData = jsonObject.getString("sysDatime");
                    //获取服务器时间，发送同步时间指令
                    new ControlUtil(false).sysServerTime(returnData);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime("获取服务器时间失败");
                new ControlUtil(false).sycTime();
            }
        });
    }

    private String initialStatus;
    private String firstMKey;
    private String secondMKey;
    private String firstWKey;
    private String secondWKey;

    /**
     * fetch mkey init1
     */
    protected void fetchMKeyForInit() {
        firstMKey = "";
        secondMKey = "";
        firstWKey = "";
        secondWKey = "";
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        postJsonEnqueue(UrlConstants.FETCH_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    firstMKey = jsonObject.getString("firstMkey");
                    secondMKey = jsonObject.getString("secondMkey");
//                    String tmpFirstMKey = "ddd";
                    String tmpFirstMKey = secondMKey;
                    new ControlUtil().init1(
                            firstMKey,
                            TextUtils.equals("02", initialStatus) ? tmpFirstMKey : secondMKey, sn);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    /**
     * feedback2server then fetch four init2
     */
    protected void feedbackToServerAndFetchFourKey() {
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        params.put("firstMKey", firstMKey);
        params.put("secondMKey", secondMKey);
        params.put("firstWKey", firstWKey);
        params.put("secondWKey", secondWKey);
        postJsonEnqueue(UrlConstants.VERIFY_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                fetchFourKeyForInit();
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    /**
     * fetch four init2
     */
    protected void fetchFourKeyForInit() {
        getEnqueue(String.format(Locale.CHINA, UrlConstants.FETCH_FOUR_KEY, sn), new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    firstMKey = jsonObject.getString("firstMKey");
                    secondMKey = jsonObject.getString("secondMKey");
                    firstWKey = jsonObject.getString("firstWKey");
                    secondWKey = jsonObject.getString("secondWKey");
                    new ControlUtil().init2(firstMKey, secondMKey, firstWKey, secondWKey, sn);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    /**
     * feedback2server then fetch syncv2
     */
    protected void feedbackToServerAndSyncTime() {
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        params.put("firstMKey", firstMKey);
        params.put("secondMKey", secondMKey);
        params.put("firstWKey", firstWKey);
        params.put("secondWKey", secondWKey);
        postJsonEnqueue(UrlConstants.VERIFY_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                syncTimeV2();
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    public void syncTimeV2() {
        getEnqueue(String.format(Locale.CHINA, UrlConstants.FETCH_WORK_KEY, sn),
                new OkHttpUtil.NetCallBack() {
                    @Override
                    public void onSucceed(String json) {
                        try {
                            JSONObject jsonObject = new JSONObject(json);
                            firstWKey = jsonObject.getString("firstWKey");
                            secondWKey = jsonObject.getString("secondWKey");
                            String timeStamp = jsonObject.getString("timeStamp");
                            // 获取服务器时间，发送同步时间指令
                            new ControlUtil().connect(firstWKey, secondWKey, sn, timeStamp);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailed(String reason) {
                        ShowToast.shortTime("获取服务器时间失败");
                        BluetoothLeService.disconnect();
                    }
                });
    }

    private void feedbackToServerAndChooseUpdateMethod() {
        HashMap<String, String> params = new HashMap<>();
        params.put("equipActualSn", sn);
        params.put("firstWKey", firstWKey);
        params.put("secondWKey", secondWKey);
        postJsonEnqueue(UrlConstants.VERIFY_MAINTAIN_KEY, params, new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {
                chooseUpdateMethod();
            }

            @Override
            public void onFailed(String reason) {
                ShowToast.shortTime(reason);
            }
        });
    }

    private void feedbackToServerForRepair() {
        getEnqueue(String.format(Locale.CHINA, UrlConstants.RESET_REPAIR_STATUS, sn), new OkHttpUtil.NetCallBack() {
            @Override
            public void onSucceed(String json) {

            }

            @Override
            public void onFailed(String reason) {

            }
        });
    }

    private void chooseUpdateMethod() {
        switch (hasNewVersion) {
            case "1":
                versionDialog.show();
                beginUpdate.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                File firmFile = updateFirmware(url);
                                if (firmFile != null) {
                                    LogUtil.d("------------------server MD5 " + md5CodeFromServer);
                                    if(TextUtils.equals(md5CodeFromServer, FileMD5Util.getFileMD5(firmFile))){
                                        // 服务器MD5文件码与下载完成的固件文件的MD5码一致，进行升级
                                        LogUtil.d("------------------local MD5 " + FileMD5Util.getFileMD5(firmFile));
                                        updateHandler.sendEmptyMessage(2);
                                        controlUtil.updateVersion(firmFile);
                                    } else {
                                        // MD5文件码不相同，下载过程中出现丢包
                                        LogUtil.d("------------------local MD5 " + FileMD5Util.getFileMD5(firmFile));
                                        updateHandler.sendEmptyMessage(6);
                                    }
                                }
                            }
                        }).start();
                    }
                });
                cancelUpdate.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        versionDialog.dismiss();
                        BluetoothLeService.disconnect();
                    }
                });
                break;
            case "2":
                ShowDialog.showConfirmDialog(mContext, "固件升级",
                        "检测到固件有新版本\n但设备无法通过蓝牙升级\n请使用章盾进行升级",
                        new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                BluetoothLeService.disconnect();
                            }
                        });
                break;
            default:
                if (GlobalData.versionV2) {
                    sendBroadcast(new Intent(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED));
                } else {
                    ShowToast.shortTime("新版本不支持该固件,请联系管理员发布新固件");
                    BluetoothLeService.disconnect();
                }
                break;
        }
    }

    /**
     * 下载新固件
     * @param url url
     */
    private File updateFirmware(String url) {
        updateHandler.sendEmptyMessage(1);

        InputStream is = null;
        FileOutputStream fos = null;
        HttpURLConnection conn = null;

        try {
            // TODO: (!TextUtils.equals(BuildConfig.FLAVOR, "publicCloud") ? UrlConstants.ROOTURL : "") + url
            url = (true ? UrlConstants.ROOTURL : "") + url;
            URL u = new URL(url);
            boolean isHttps = url.startsWith("https");
            if (isHttps) {
                conn = (HttpsURLConnection) u.openConnection();
                ((HttpsURLConnection) conn).setSSLSocketFactory(
                        OkHttpUtil.createSSLSocketFactory());
                ((HttpsURLConnection) conn).setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String s, SSLSession sslSession) {
                        // now all
                        return true;
                    }
                });
            } else {
                conn = (HttpURLConnection) u.openConnection();
            }
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(20000);
            conn.connect();

            File downloadFile = new File(FileUtil.createDirFile(mContext, DOWNLOAD_FIRM_PATH),
                    "seal_firm");
            if (downloadFile.exists()) {
                LogUtil.d("已存在固件删除:" + downloadFile.delete());
            }
            fos = new FileOutputStream(downloadFile);

            is = conn.getInputStream();
            int length = conn.getContentLength();
            int count = 0;
            int ret;
            byte[] buf = new byte[1024];
            while ((ret = is.read(buf)) != -1) {
                count += ret;
                fos.write(buf, 0, ret);
            }
            LogUtil.d("固件下载长度:" + count + ":" + length);
            if (count == length) {
                return downloadFile;
            }
        } catch (Exception e) {
            e.printStackTrace();
            updateHandler.sendEmptyMessage(5);
            BluetoothLeService.disconnect();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
